#pragma once

#include <string>
#include <cstdint>
#include <cstdlib>
#include <cassert>
#include <utility>
#include <functional>


#define CARBON_NS  carbon 
#define CARBON_NS_BEGIN namespace CARBON_NS {
#define CARBON_NS_END }


#define CARBON_NONCOPYABLE(ClassName) \
    ClassName(const ClassName&) = delete; \
    ClassName& operator=(const ClassName&) = delete;

#define CARBON_NONMOVABLE(ClassName) \
    ClassName(ClassName&&) = delete; \
    ClassName& operator=(ClassName&&) = delete;

#define CARBON_NONINSTANCIABLE(ClassName) \
    ClassName() = delete; \
    ~ClassName() = delete;

#define CARBON_INLINE  inline

#define CARBON_FILE_SEP_S "/"
#define CARBON_FILE_SEP   '/'


#define CARBON_SYSTEM_TIMESTAMP_USEC() \
    std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count()

#define CARBON_NO_EXCEPT   noexcept
#define CARBON_API         __attribute__((visibility("default")))

#define CARBON_FILE_LINE  __FILE__, __LINE__


#if __cplusplus__ >= 202002L
#define CARBON_NO_DISCARD  [[nodiscard]]
#endif /// __cplusplus__

CARBON_NS_BEGIN

struct Noncopyable {
    Noncopyable() = default;
    Noncopyable(const Noncopyable&) = delete;
    Noncopyable& operator=(const Noncopyable&) = delete;
};

struct Noninstantiable {
    Noninstantiable() = delete;
    ~Noninstantiable() = delete;
};

using String = std::string;
using StringView = std::string_view;
using RunnableFn = std::function<void()>;

#ifdef __linux__
typedef int fd_t;
#define CARBON_INVALID_FD (-1)

typedef int socket_t;
#define CARBON_INVALID_SOCKET (-1)
#endif // __linux__


CARBON_NS_END
